﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Dict.Config;
using Dict.Blo;
using Battle;
using ProtoBuf.Message;

namespace UI
{
    public class ArrayPage : Page
    {
        /// <summary>
        /// 阵容位置
        /// </summary>
        public List<ArrayPosition> positions;

        /// <summary>
        /// 属性tab页
        /// </summary>
        public PropertyTab propertyTab;

        /// <summary>
        /// 装备tab页
        /// </summary>
        public EquipTab equipTab;

        /// <summary>
        /// 料理tab页
        /// </summary>
        public CookTab cookTab;

        /// <summary>
        /// 宝石tab页
        /// </summary>
        public MineTab mineTab;

        /// <summary>
        /// 总战力
        /// </summary>
        public UILabel fightPower;

        /// <summary>
        /// 人物站立位置
        /// </summary>
        /// 
        public GameObject heroAniPos;
        GameObject m_heroAni;

        /// <summary>
        /// 装备位置
        /// </summary>
        public List<EquipPosition> equipPositons;

        /// <summary>
        /// 右侧tab页按钮
        /// </summary>
        public UIToggle tabProperty;
        public UIToggle tabEquip;
        public UIToggle tabCook;
        public UIToggle tabMine;

        /// <summary>
        /// 查看他人阵容特殊需要
        /// </summary>
        public UILabel labTitle;
        public GameObject btnMaster;
        public GameObject btnReplace;
        public GameObject btnUpgrade;
        public GameObject topBar;
        public GameObject zhuzhen;
        public GameObject buzhen;

        UIOtherPlayerData otherPlayerData;

        int curPosition;
        string heroGuid = "";
        string heroId;
        bool isOtherPlayer = false;


        /// <summary>
        /// 人物动画旋转
        /// </summary>
        Vector3 startDragPos;
        bool isDragging = false;

        /// <summary>
        /// 更换队长
        /// </summary>
        bool isLeaderDragging = false;
        Vector3 leaderStartDragPos;
        Vector3 leaderStartMousePos;
        int curDragIndex = 0;
        //int endDragIndex = 0;

        //是否选中装备的alltab
        bool choseEquipTabAll = true;

        public int CurPosition
        {
            get
            {
                return curPosition;
            }
        }

        void Awake()
        {
            curPosition = 0;
            isDragging = false;
        }

        public void UpdateAll()
        {
            //初始化阵容人物icon
            for (int i = 0; i < positions.Count; i++)
            {
                positions[i].UpdatePosition(otherPlayerData);
            }

            //总战力 TODO
            //fightPower.text = StaticData.playerData.SimplerPlayerData.GetFightPower().ToString();

            UpdateCurPosition();
        }

        public void UpdateCurPosition()
        {
            OnArrayPosClick(curPosition);
        }

        IEnumerator LoadHeroAni(Dict.DataModel.TableHero dh , string weaponId) {
            yield return StartCoroutine(ResourceLoader.GetInstance().modelLoader.LoadModel(dh.resName, (asset) => {
                GameObject heroAni = asset as GameObject;
                if (heroAni != null)
                {
                    heroAni.name = dh.resName;
                    heroAni.transform.parent = heroAniPos.transform;
                    heroAni.transform.localPosition = Vector3.zero; 
                    heroAni.transform.localEulerAngles = Vector3.zero;
                    heroAni.GetComponent<LegacyAnimation>().Play(AniName.STAND, WrapMode.Loop);
                    heroAni.GetComponent<ModelRenderKit>().SetModelScale((float)dh.ScaleFactor);
                    heroAni.GetComponent<ModelRenderKit>().SwitchLod(false);
                    m_heroAni = heroAni;
                }
            }));
            if (m_heroAni != null)
            {
                yield return StartCoroutine(m_heroAni.GetComponent<ModelRenderKit>().LoadWeapons(dh.id, weaponId));
                CommonMethod.ChangeLayer(m_heroAni.transform, heroAniPos.layer);
            }
            else {
                Debug.LogError("[ArrayPage] LoadHeroAni Failed. resName: " + dh.resName);
            }
        }

        public void OnArrayPosClick(int index)
        {
            Dictionary<int, UIHeroFormation> battleCamps = StaticData.playerData.InstPlayerData.BattleCamps;

            if (isOtherPlayer)
                battleCamps = otherPlayerData.formations;

            if (battleCamps[index].hero != null)
            {
                curPosition = index;

                positions[curPosition - 1].GetComponent<UIToggle>().Set(true);

                //string id = battleCamps[index].hero.heroId;
                this.heroId = battleCamps[index].hero.heroId;
                heroGuid = battleCamps[index].hero.guid;

                //人物动画
                foreach( Transform tran in heroAniPos.transform)
                {
                    ResourceLoader.GetInstance().modelLoader.UnloadModel(tran.gameObject,tran.name);
                    tran.GetComponent<ModelRenderKit>().SwitchLod(true);
                }
                heroAniPos.transform.DestroyChildren();

                string weaponId = "";
                if (battleCamps[index].equipments[0] != null)
                    weaponId = battleCamps[index].equipments[0].equipId;
                StopCoroutine("LoadHeroAni");
                StartCoroutine(LoadHeroAni(battleCamps[index].hero.heroData, weaponId));
                //装备
                for (int i = 0; i < battleCamps[index].equipments.Length; i++)
                {
                    if (battleCamps[index].equipments[i] != null)
                    {
                        equipPositons[i].SetEquip(battleCamps[index].equipments[i]);
                    }
                    else
                    {
                        equipPositons[i].ClearPosition();
                    }
                }

                //饰品
                for (int i = 0; i < battleCamps[index].treasures.Length; i++)
                {
                    if (battleCamps[index].treasures[i] != null)
                    {
                        equipPositons[i + 4].SetTreasure(battleCamps[index].treasures[i]);
                    }
                    else
                    {
                        equipPositons[i + 4].ClearPosition();
                    }
                }

                if (equipTab.gameObject.activeSelf)
                {
                    if (choseEquipTabAll)
                        equipTab.SetInnerTab(0);
                    else
                        equipTab.UpdateTab();
                }

                if (propertyTab.gameObject.activeSelf)
                {
                    string name = "";
                    if (isOtherPlayer && (battleCamps[index].hero.heroData.heroClass == (int)HeroClass.Main_Actor_Man ||
                        battleCamps[index].hero.heroData.heroClass == (int)HeroClass.Main_Actor_Woman) )
                        name = otherPlayerData.playerName;

                    //属性信息
                    propertyTab.SetHero(battleCamps[index], name);
                }

                if(cookTab.gameObject.activeSelf)
                {
                    cookTab.UpdateScrollView();
                }

                if (mineTab.gameObject.activeSelf)
                {
                    mineTab.UpdateScrollView();
                }
            }
            else if(!isOtherPlayer)
            {
                if (battleCamps[index].UnlockLevel <= StaticData.playerData.level)
                {
                    positions[curPosition - 1].GetComponent<UIToggle>().value = true;

                    string option = "index=" + index.ToString()+ "&openPageType=hero";
                    PageManager.Instance.OpenPage("HeroReplacePage", option);
                    HeroReplacePage page = (HeroReplacePage)PageManager.Instance.GetDictPage("HeroReplacePage");
                    page.m_callback = this.OnHeroGoArrayCallback;

                }
                else
                {
                    positions[curPosition - 1].GetComponent<UIToggle>().value = true;
                    BoxManager.CreatePopupTextBox(string.Format(TableTextBlo.GetText("levelTooLow"),battleCamps[index].UnlockLevel));
                }
            }
        }

        void OnHeroGoArrayCallback(int index)
        {
            curPosition = index;
            positions[curPosition - 1].GetComponent<UIToggle>().value = true;
        }

        /// <summary>
        /// 助阵
        /// </summary>
        public void OnZhuzhenClick()
        {
            pageManager.OpenPage("UILuck", "pos=" + curPosition.ToString());
        }

        /// <summary>
        /// 布阵
        /// </summary>
        public void OnBuzhenClick()
        {
            pageManager.OpenPage("FormationPopupPage", "");
        }

        public void OnEquipPosClick(int index)
        {
            if(isOtherPlayer)
            {
                return;
            }

            if (equipPositons[index].equipGuid != null)
            {
                if (index < 4)
                {
                    UIEquipment equip = StaticData.playerData.GetUIEquipment(equipPositons[index].equipGuid);
                    string options = "equipGuid=" + equipPositons[index].equipGuid;
                    options += "&equipId=" + equip.equipId;
                    options += "&type=" + "1";//1是装备
                    options += "&heroPostion=" + curPosition;
                    options += "&heroId=" + heroId;
                    PageManager.Instance.OpenPage("EquipmentUIPage", options);
                }
                else
                {
                    UITreasure equip = StaticData.playerData.GetUITreasure(equipPositons[index].equipGuid);
                    string options = "equipGuid=" + equipPositons[index].equipGuid;
                    options += "&equipId=" + equip.treasureId;
                    options += "&type=" + "2";//2是饰品
                    options += "&heroPostion=" + curPosition;
                    options += "&heroId=" + heroId;
                    PageManager.Instance.OpenPage("EquipmentUIPage", options);
                }
                EquipMentUIPanelPage page = (EquipMentUIPanelPage)PageManager.Instance.GetDictPage("EquipmentUIPage");
                page.m_callback = this.OnOffEquipCallback;
            }
            else
            {
                if(index < 4)
                {
                    if(!StaticData.playerData.InstPlayerData.HaveEquipForPos(index))
                    {
                        pageManager.OpenPage("ObtainWayPage", "showFirstEquip=" + (index + 1).ToString());
                        return;
                    }
                }
                else
                {
                    if(StaticData.playerData.level < Dict.Blo.DictConfigBlo.GetPlunderPVPLimitLevel()) 
                    {
                        BoxManager.CreatePopupTextBox(string.Format(TableTextBlo.GetText("treasure_equip_level_limit"), Dict.Blo.DictConfigBlo.GetPlunderPVPLimitLevel()));
                        return;
                    }
                    if(!StaticData.playerData.InstPlayerData.HaveTreasureForPos(index))
                    {
                        int type = index == 4 ? 1 : 0;
                        pageManager.OpenPage("ObtainWayPage", "showTreasureWay=" + type.ToString());
                        return;
                    }
                }
                tabEquip.value = true;
                equipTab.SetInnerTab(index + 1);
            }
        }

        void OnOffEquipCallback(string guid, string type, int pos)
        {
            UIHeroFormation formation = StaticData.playerData.InstPlayerData.GetBattleCamp(pos);
            if (type == "1")
            {
                UIEquipment equip = StaticData.playerData.GetUIEquipment(guid);
                formation.UpdateEquip("", equip.equipData.type);
            }
            else
            {
                UITreasure treasure = StaticData.playerData.GetUITreasure(guid);
                int newPos = 5;
                if (treasure.treasureData.type == 0)
                    newPos = 6;
                formation.UpdateTreasure("", newPos);
            }
            
            choseEquipTabAll = false;
            UpdateCurPosition();

            if (equipTab.gameObject.activeSelf)
            {
                equipTab.UpdateTab();
            }

        }

        string myGuid;
        public void OnPropertyTab()
        {
            if(isOtherPlayer)
                return;
            Dictionary<int, UIHeroFormation> battleCamps = StaticData.playerData.InstPlayerData.BattleCamps;
            if (battleCamps[curPosition].hero != null)
            {
                propertyTab.SetHero(battleCamps[curPosition]);
            }
        }

        public void OnEquipTab()
        {
            equipTab.gameObject.SetActive(true);
            equipTab.UpdateTab();
        }

        public void OnCookTab()
        {
            cookTab.UpdateScrollView();
        }

        public void OnMineTab()
        {
            mineTab.UpdateScrollView();
        }

        public void OnReplaceBtn()
        {
            Dictionary<int, UIHeroFormation> battleCamps = StaticData.playerData.InstPlayerData.BattleCamps;
            if (battleCamps[curPosition].hero.IsUserHero && StaticData.playerData.level < Dict.DictDataManager.Instance.tableGameConfigureDao.currentData.SwapMainHeroLevel)
            {
                BoxManager.CreatePopupTextBox(string.Format(TableTextBlo.GetText("change_main_hero_level"), Dict.DictDataManager.Instance.tableGameConfigureDao.currentData.SwapMainHeroLevel));
                return;
            }
            string option = "index=" + curPosition.ToString() + "&openPageType=hero";
            PageManager.Instance.OpenPage("HeroReplacePage", option);
        }

        public void OnUpgradeBtn()
        {
            PageManager.Instance.OpenPage("characterRemotePage", "guid=" + heroGuid + "&tab=0");
        }

        public void OnStrengthBtn()
        {
            PageManager.Instance.OpenPage("Master", "pos=" + curPosition.ToString());
        }

        public void OnPetBtn()
        {
            string option = "index=" + curPosition.ToString() + "&openPageType=pet";
            Dictionary<int, UIHeroFormation> battleCamps = StaticData.playerData.InstPlayerData.BattleCamps;
            if (battleCamps[curPosition].pet ==null)
            {
                PageManager.Instance.OpenPage("HeroReplacePage", option);
                // HeroReplacePage page = (HeroReplacePage)PageManager.Instance.GetDictPage("HeroReplacePage");
                
            }
            else
            {
                //打开宠物详情
                PageManager.Instance.OpenPage("PetPage", option);
            }

        }

        public void OnHeroClick()
        {
            if (isOtherPlayer)
                return;

            PageManager.Instance.OpenPage("UIHeroPage", "guid=" + heroGuid +"&showUnloadHero=false");
            var heroPage = PageManager.Instance.currentPage as UIHeroPage;
            var eventPage = heroPage.GetComponent<UIHeroEvent>();
            eventPage.switchHeroHandler = delegate
            {
                OnReplaceBtn();
            };
        }

        public void OnHeroDragStart()
        {
            if (m_heroAni != null)
            {
                startDragPos = Input.mousePosition;
                isDragging = true;
            }
        }

        public void OnHeroDragEnd()
        {
            isDragging = false;
        }

        public void OnPositionDragStart(int index)
        {
            if (isOtherPlayer)
                return;
            Dictionary<int, UIHeroFormation> battleCamps = StaticData.playerData.InstPlayerData.BattleCamps;
            if(battleCamps[index].hero != null)
            {
                curDragIndex = index - 1;
                leaderStartDragPos = positions[curDragIndex].gameObject.transform.localPosition;
                leaderStartMousePos = Input.mousePosition;
                isLeaderDragging = true;
            }
        }

        public void OnPositionDragEnd()
        {
            if (isOtherPlayer)
                return;
            if (!isLeaderDragging)
                return;

            isLeaderDragging = false;
            int endIndex = GetDragEndPosIndex(positions[curDragIndex].gameObject.transform.localPosition);
            Dictionary<int, UIHeroFormation> battleCamps = StaticData.playerData.InstPlayerData.BattleCamps;
            if (endIndex != curDragIndex)
            {
                if(battleCamps[endIndex + 1].hero == null)
                {
                    positions[curDragIndex].gameObject.transform.localPosition = leaderStartDragPos;
                    return;
                }

                //endDragIndex = endIndex;
                CSFormationExChange msg = new CSFormationExChange();
                msg.fromPos = curDragIndex + 1;
                msg.toPos = endIndex + 1;
                NetAPI.SendHttp(OpDefine.CSFormationExChange, msg, FromationExchangeRecv);
            }
            else
            {
                positions[curDragIndex].gameObject.transform.localPosition = leaderStartDragPos;
            }
        }

        void FromationExchangeRecv(NetWork.Packets.Packet packet, bool success)
        {
            positions[curDragIndex].gameObject.transform.localPosition = leaderStartDragPos;
            if (success)
            {
                SCFormationExChange msg = packet.kBody as SCFormationExChange;

                StaticData.playerData.InstPlayerData.InitBattleCamp(msg.formationList,true);
                StaticData.playerData.InstPlayerData.FixHeroOwners();
                
                choseEquipTabAll = false;

                UpdateAll();
            }
        }

        int GetDragEndPosIndex(Vector3 v)
        {
            Dictionary<int, UIHeroFormation> battleCamps = StaticData.playerData.InstPlayerData.BattleCamps;
            foreach (var item in battleCamps) 
            {
                if(item.Value.hero != null && item.Value.campPos - 1 != curDragIndex)
                {
                    ArrayPosition position = positions[item.Value.campPos - 1];
                    Vector3 v1 = position.gameObject.transform.localPosition;
                    if(Mathf.Abs(v.y - v1.y) < position.GetComponent<UIWidget>().height/2)
                    {
                        return item.Value.campPos - 1;
                    }
                }
            }
            
            return curDragIndex;
        }

        void Update()
        {
            //模型拖动旋转
            if (m_heroAni != null && isDragging)
            {
                Vector3 v = Input.mousePosition;
                m_heroAni.transform.Rotate(new Vector3(0, startDragPos.x - v.x, 0));
                startDragPos = v;
            }

            //总战力
            if (isOtherPlayer)
                fightPower.text = otherPlayerData.fightPower.ToString();
            else
                fightPower.text = StaticData.playerData.InstPlayerData.GetFightPower().ToString();

            //更换阵容位置
            if(isLeaderDragging)
            {
                Vector3 v = Input.mousePosition;
                positions[curDragIndex].gameObject.transform.localPosition = new Vector3(leaderStartDragPos.x, leaderStartDragPos.y + (v.y - leaderStartMousePos.y) * GetRoot().pixelSizeAdjustment, leaderStartDragPos.z);
            }
        }

        private UIRoot root;
        private UIRoot GetRoot()
        {
            if (root == null)
            {
                root = NGUITools.FindInParents<UIRoot>(gameObject);
            }
            return root;
        }

        override public void OnCoverPageRemove()
        {
            m_heroAni.SetActive(true);
            choseEquipTabAll = false;
            UpdateAll();
        }

        public override void OnCoverPageOpen()
        {
            m_heroAni.SetActive(false);
            base.OnCoverPageOpen();
        }

        #region 查看他人阵容
        void FindOtherPlayerInfoCallback(NetWork.Packets.Packet packet, bool success)
        {
            if (success)
            {
                SCFindPlayerInfo msg = packet.kBody as SCFindPlayerInfo;
                otherPlayerData = new UIOtherPlayerData();
                otherPlayerData.InitData(msg.formationInfo);

                OpenOtherPlayerMode();
            }
        }

        void OpenOtherPlayerMode()
        {
            isOtherPlayer = true;
            labTitle.text = otherPlayerData.playerName;
            btnMaster.SetActive(false);
            btnReplace.SetActive(false);
            btnUpgrade.SetActive(false);
            topBar.SetActive(false);
            zhuzhen.SetActive(false);
            buzhen.SetActive(false);
            cookTab.gameObject.SetActive(false);
            mineTab.gameObject.SetActive(false);
            equipTab.gameObject.SetActive(false);
            tabEquip.gameObject.SetActive(false);
            tabCook.gameObject.SetActive(false);
            tabMine.gameObject.SetActive(false);
            propertyTab.btnSkillSet.SetActive(false);
            
            tabProperty.Set(true);
            tabEquip.Set(false);

            curPosition = 1;
            UpdateAll(); 

            gameObject.GetComponent<PageTweener>().Play();

            //页面初始动画 
            for (int i = 0; i < positions.Count; i++)
            {
                UITweener[] list = positions[i].transform.GetComponents<UITweener>();
                for (int j = 0; j < list.Length; j++)
                {
                    list[j].ResetToBeginning();
                    list[j].PlayForward();
                }
            }
        }

        void BackToNormalMode()
        {
            isOtherPlayer = false;
            otherPlayerData = null;
            labTitle.text = TableTextBlo.GetText("array");
            btnMaster.SetActive(true);
            btnReplace.SetActive(true);
            btnUpgrade.SetActive(true);
            topBar.SetActive(true);
            zhuzhen.SetActive(true);
            buzhen.SetActive(true);
            propertyTab.btnSkillSet.SetActive(true);
            propertyTab.gameObject.SetActive(false);
            tabEquip.gameObject.SetActive(true);
            equipTab.gameObject.SetActive(true);
            tabCook.gameObject.SetActive(true);
            tabMine.gameObject.SetActive(true);

            tabProperty.Set(false);
            tabEquip.Set(true);
        }

        #endregion


        override protected void DoOpen()
        { 
            if(options.ContainsKey("userId"))
            {
                CSFindPlayerInfo msg = new CSFindPlayerInfo();
                msg.playerId = long.Parse(options["userId"]);
                msg.serverId = int.Parse(options["serverId"]);
                NetAPI.SendHttp(OpDefine.CSFindPlayerInfo, msg, FindOtherPlayerInfoCallback);
                return;
            }

            if(isOtherPlayer)
            {
                BackToNormalMode();
            }

            if (curPosition == 0)
            {
                curPosition = 1;
            }
            if(options.ContainsKey("pos"))
            {
                //强制选中第pos位置，并切到装备tab
                curPosition = int.Parse(options["pos"]);
                options.Remove("pos");
                tabEquip.Set(true);
            }

            if (options.ContainsKey("rightTab"))
            {
                if (options["rightTab"] == "2")
                {
                    tabCook.Set(true);
                    cookTab.UpdateScrollView();
                }
                if (options["rightTab"] == "3")
                {
                    tabMine.Set(true);
                    mineTab.UpdateScrollView();
                }
                options.Remove("rightTab");
            }
            else
            {
                tabEquip.Set(true);
            }

            choseEquipTabAll = true;
            UpdateAll();
            
            gameObject.GetComponent<PageTweener>().Play();

            //页面初始动画 
            for (int i = 0; i < positions.Count; i++)
            {
                UITweener[] list = positions[i].transform.GetComponents<UITweener>();
                for (int j = 0; j < list.Length; j++)
                {
                    list[j].ResetToBeginning();
                    list[j].PlayForward();
                }
            }
        }

        override protected void DoClose()
        {
            foreach (Transform tran in heroAniPos.transform)
            {
                ResourceLoader.GetInstance().modelLoader.UnloadModel(tran.gameObject, tran.name);
                tran.GetComponent<ModelRenderKit>().SwitchLod(true);
            }
        }

    }


}